home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-06-16 | 14.5 KB | 444 lines | [TEXT/MPS ] |
- ;____________________________________________________________________________________
- ;
- ; File: disk.a
- ;
- ; Contains: The assembly driver header and some misc other stuff
- ; Part of the Example SCSI Driver
- ;
- ; Copyright: © 1993-94 by Apple Computer, Inc., all rights reserved.
- ;
- ;____________________________________________________________________________________
-
-
-
- BLANKS ON
-
- PRINT OFF
- INCLUDE 'SysEqu.a'
- INCLUDE 'SysErr.a'
- INCLUDE 'Traps.a'
-
- PRINT ON
-
- CASE OBJ
-
-
- ASCSIDisk MAIN EXPORT
-
- CASE OBJECT
- EXPORT geticon
- EXPORT A5Setup
- IMPORT dropen, prime, control, status ; Disk.c
- IMPORT drclose, getRefNum ; Disk.c
-
- Start
- ; Header for the 'Driver Plus'
-
- bra.w DInst ; 4 bytes
- dc.l 1 ; unused
- bra.w D2Inst ; 4 bytes
- DC.W $2324 ; signature
- DC.W 1 ; ddType
- DC.W 1 ; version
- DC.W 1 ; sbDevID
- DC.W 1 ; sbDevType
- drvrsize DC.L 0 ; size of driver (in bytes)
- ;
- ; Note: 'chksum' is the last Header+ field, and must
- ; start just before the DiskDrvr label
- ;
- chksum DC.L 0 ; driver checksum (word sum)
-
-
- DiskDrvr ; This is where dCtlDriver in the DCE should be pointing.
-
- ; Regular driver header
-
- DC.W $6F00 ; was $4F; uses dNeedTime now
- DC.W 0,0 ; no delay or EMask
- DC.W 0 ; no menu
-
- ; Entry point offset table
-
- DC.W DiskOpen-DiskDrvr ; open
- DC.W DiskPrime-DiskDrvr ; prime
- DC.W DiskControl-DiskDrvr ; control
- DC.W DiskStatus-DiskDrvr ; status
- DC.W DiskClose-DiskDrvr ; close
-
- DName ; Must start after offset table and should occupy 8 bytes.
-
- STRING ASIS
-
- DC.B 7 ; name length
- DC.B '.XMPL00' ; name to open - last two bytes will
- ; unique value (checksum) inserted.
- ; Or not, we haven't figured out why!
-
- ;
- ; WARNING: Sigoffs must start at an offset of 26 (dec) from
- ; DiskDrvr. If you change this, the installer program
- ; (routines.c, routines.a) may no longer work for plugging
- ; and unplugging a driver, so be careful!
- ;
- SigValue EQU $41BD30B0 ; arbitrary signature value
- SigOffs DC.L SigValue ; offset 26 from DiskDrvr
- openmap DC.W 0 ; offset 30 from DiskDrvr
- mountflag DC.W 0 ; offset 32 from DiskDrvr
-
- ;_______________________________________________________________________
- ;
- ; RemoveDrvr
- ;
- ; This deallocates the heap space of an identical driver that is
- ; being opened. After the DisposPtr, the 'older' driver continues
- ; to set up things to handle the new drive.
- ;
- ; On entry (called by jmp), a0 = 'Start' addr of driver to be
- ; deallocated
- ;_______________________________________________________________________
-
- RemoveDrvr
- _DisposPtr ,SYS ; away with thee!
- bra.w InstallDCE ; continue setting up
-
-
- ;_______________________________________________________________________
- ;
- ; A5Setup():
- ;
- ; This returns the previous a5 value in D0, and sets A5 to its new value.
- ;
- ;_______________________________________________________________________
-
- A5Setup
- move.l a5,d0
- move.l 4(sp),a5
- rts
-
- ;_______________________________________________________________________
- ;
- ; Routine: geticon()
- ;
- ; Returns a pointer to the icon.
- ;
- ;_______________________________________________________________________
-
- geticon
- pea theicon
- move.l (sp)+,d0
- rts
-
- ;_______________________________________________________________________
- ;
- ; Routine: DiskOpen
- ; Arguments: A0 (input) -- pointer to request parameter block
- ; A1 (input) -- DCE pointer for driver.
- ; Function: This is just a stub now because _Open is too brain-damaged
- ; to use with multiple drives handled by a single driver.
- ; The real Open code (dropen) is called without involving
- ; the _Open trap at all.
- ;_______________________________________________________________________
-
- DiskOpen
- moveq.l #0,d0 ; say it's OK
- move.w d0,ioResult(a0) ; see I.M. II, p. 193
- bra.s DriverDone2
-
- ;_______________________________________________________________________
- ;
- ; Routine: DiskClose
- ; Arguments: A0 (input) -- pointer to request parameter block
- ; A1 (input) -- DCE pointer for driver.
- ; Function: If this is the last drive for this driver, remove the
- ; VBL task, shutdown task, and dispose of driver locals.
- ;_______________________________________________________________________
-
- DiskClose
- move.l a5,-(sp) ; save A5
- move.l dCtlStorage(a1),a5 ; setup A5
- move.l a0,-(sp) ; param block
- move.l a1,-(sp) ; DCE
- jsr drclose
- bra.s DriverDone
-
- ;_______________________________________________________________________
- ;
- ; Routine: DiskControl
- ; Arguments: A0 (input) -- pointer to control call parameter block
- ; A1 (input) -- DCE pointer for driver.
- ; CSCode:
- ; 1 = KillIO
- ; 5 = Verify
- ; 6 = Format
- ; 7 = Eject
- ; 8 = SetTagBuffer (for 12-byte field only)
- ; 17 = PhysIo (read/write physical, not logical, blocks)
- ; 20 = Icon return (RSRC ID)
- ; 21 = pointer to icon and string
- ;
- ;_______________________________________________________________________
-
- DiskControl
- move.l a5,-(sp) ; save A5
- move.l dCtlStorage(a1),a5 ; setup A5
- move.l a0,-(sp) ; param block
- move.l a1,-(sp) ; DCE
- jsr control
- bra.s DriverDone
-
- ;_______________________________________________________________________
- ;
- ; Routine: DiskStatus
- ; Arguments: A0 (input) -- pointer to status call parameter block:
- ;
- ; CSCode:
- ; 8 = DrvSts (get drive status)
- ;_______________________________________________________________________
-
- DiskStatus
- move.l a5,-(sp) ; save A5
- move.l dCtlStorage(a1),a5 ; setup A5
- move.l a0,-(sp) ; param block
- move.l a1,-(sp) ; DCE
- jsr status
- bra.s DriverDone
-
- ;_______________________________________________________________________
- ;
- ; Routine: DiskPrime
- ; Arguments: A0 (input) -- pointer to request parameter block
- ; A1 (input) -- pointer to disk DCE
- ; Function: The prime entry point is used for drive read/write.
- ;
- ;_______________________________________________________________________
-
- DiskPrime
- move.l a5,-(sp) ; save A5
- move.l dCtlStorage(a1),a5 ; setup A5
- move.l a0,-(sp) ; param block
- move.l a1,-(sp) ; DCE
- jsr prime
-
- DriverDone ; common for all driver calls
- move.l (sp)+,a1 ; restore DCE pointer
- move.l (sp)+,a0 ; restore PB pointer
- move.l (sp)+,a5 ; restore A5
- DriverDone2
- cmp.w #1,d0 ; Magic "Handled Async" return from DoNewSCSI?
- bne.b @DriverDone3 ; Nope, handle normally
- moveq #0,d0 ; set return to noErr
- bra.b @return ; mosey on outta here (Let completion routing call iodone)
- @DriverDone3
- tst.w d0 ; set z bit for test <AG>
- beq.s @NoError ; ... don't update error field unless there is an error <AG>
- move.w d0,DskErr ; save last error for file system
- @NoError
- btst #noQueueBit,ioTrap(a0) ; immediate call?
- bne.s @Return ; if so, just do an rts
- move.l JIODone,-(sp) ; else jump to JIODone
- @Return
- rts
-
-
-
- ;----------------------------------------------
- ;
- ; The icon is currently hard-coded. It would be nice to make it
- ; more dynamic.
- ;
-
- theicon ; 256 bytes long
-
- dc.w $0000, $8000, $0001, $C000, $0003, $E000, $0867, $F000
- dc.w $14AF, $7800, $173E, $3C00, $107C, $1E00, $2478, $0F02
- dc.w $4070, $0786, $8020, $03CA, $0018, $01F2, $0007, $FFE2
- dc.w $FC00, $FF84, $1E00, $7F84, $3E00, $1F0E, $7980, $000F
- dc.w $F1C0, $000E, $79C0, $000C, $3DC0, $0008, $1F80, $0004
- dc.w $0F0F, $FE04, $0710, $0104, $0310, $0384, $0118, $0F44
- dc.w $011C, $1E44, $011E, $3C44, $022F, $7884, $0447, $F108
- dc.w $0383, $E0F0, $0001, $C000, $0000, $8000, $0000, $0000
-
- dc.w $0000, $8000, $0001, $C000, $0003, $E000, $0867, $F000
- dc.w $1CEF, $F800, $1FFF, $FC00, $1FFF, $FE00, $3FFF, $FF02
- dc.w $7FFF, $FF86, $FFFF, $FFCE, $FFFF, $FFFE, $FFFF, $FFFE
- dc.w $FFFF, $FFFC, $1FFF, $FFFC, $3FFF, $FFFE, $7FFF, $FFFF
- dc.w $FFFF, $FFFE, $7FFF, $FFFC, $3FFF, $FFF8, $1FFF, $FFFC
- dc.w $0FFF, $FFFC, $07FF, $FFFC, $03FF, $FFFC, $01FF, $FF7C
- dc.w $01FF, $FE7C, $01FF, $FC7C, $03EF, $F8FC, $07C7, $F1F8
- dc.w $0383, $E0F0, $0001, $C000, $0000, $8000, $0000, $0000
- ; Drive location string (with length byte)
- ds.b 32
-
- align
-
-
-
- ;--------------------------------------------------------------
- ;
- ; The SCSI driver loader will get to here.
- ; a0 -> the partition table. d7 = default data start area (in case partition map is bad)
- ; d5 = SCSI ID or Device Ident of device this driver came from.
- ; Need to: Get DCE, point DCE at driver, open driver, fill in
- ; driver locals based on passed environment.
- ;
-
-
- D2Inst
- bset.l #29,d5 ; use this bit as a "Driver43" flag
- bra.b DrvrInst ; have at it
-
- DInst
- bclr #29,d5 ; NOT a "Driver43"
- DrvrInst
- movem.l a2-a6/d2-d7,-(sp)
-
- ; Since the ROM allocates space in the system heap for the
- ; driver in a multiple of a disk block size, we can
- ; return the unused heap space since we know the exact
- ; size in bytes.
- ;
- move.l a0,a4 ; save the partition table pointer
- lea Start,a0 ; start of driver
- move.l drvrsize,d0 ; # of bytes in driver
- _SetPtrSize ; cut back to actual size
-
- moveq #0,d0 ; Clear out d0
- moveq #0,d1 ; Clear out d1
- move.w UnitNtryCnt,d0 ; check all DCEs SCSI and above
- sub.l #32,d0 ; don't look below that
- move.l UTableBase,a1 ; find unit table
- move.w UnitNtryCnt,d1 ; The number of DCEs
- lsl.l #2,d1 ; Multiply by the size of an entry
- add.w d1,a1 ; point to the end of the table
- @0
- move.l -(a1),d2 ; check next lower DCE
- beq.s @1 ; if empty hndl, try again
- move.l d2,a2 ; get handle to SCSI DCE
- move.l (a2),a0 ; get ptr to DCE
- move.l (a0),a2 ; get address of driver
- cmpi.l #SigValue,Sigoffs-DiskDrvr(a2) ; same signature?
- bne.s @1 ; if not, keep looking
- cmp.l chksum-DiskDrvr(a2),d3 ; same checksum?
- bne.s @1 ; if not, keep looking
- ;
- ; Now we've found a driver which can handle multiple
- ; drives, so we'll jump to it. There the code does a
- ; DisposPtr on this duplicate driver code, and then goes
- ; on to the InstallDCE code.
- ;
- lea Start,a0 ; set up for the DisposPtr
- jmp RemoveDrvr-DiskDrvr(a2) ; go to his RemoveDrvr...
- @1
- dbra d0,@0 ; try next slot in table
-
- ;
- ; Bit 31 of d5 is 0 if we were booted by the ROM (in
- ; which case we want to bump up the system heap size),
- ; else it's set by the Installer (leave heap alone).
- ;
- tst.l d5 ; if Installer called us...
- bmi.s InstallDCE ; don't do anything else
-
- btst #$29,d5 ; New API?
- bne.b InstallDCE ; Yep, don't do SetAppBase
-
- move.l SysZone,a0 ; get start of system heap
- move.l (a0),a0 ; get bkLim
- add.w #$3000,a0 ; add 12K
- move.l TheZone,-(sp) ; save so it doesn't get trashed
- _SetAppBase ; (boot blocks can make a larger
- ; system heap if they want to)
- move.l (sp)+,TheZone ; fixes startup screen bug
-
- InstallDCE
- ; First we decide if we are running in a SCSI Manager 4.3 Environment
- ; If so we get a drefnum from the getRefNum function
- ; otherwise we get one the old fashioned way - ie use the assigned one.
-
- movem.l a0-a2/d1-d2,-(sp)
- move.l d5,-(sp) ; push the SCSI ID/Device Ident
- jsr getRefNum ; Look for New SCSI Manager and get RefNum
- addq.l #4,sp ; pop parameters
- movem.l (sp)+,a0-a2/d1-d2 ; restore regs
- move.w d0,d4 ; save a copy of dRefNum
- beq.s InitExit ; valid dRefNum? no->skip install
- not.w d4 ; turn it into a unit number
- _DrvrInstall ; do the DCE shuffle
-
- asl.w #2,d4 ; * 4
- move.l UTableBase,a1 ; point at unit table
- move.l 0(a1,d4.w),a0 ; get the DCE Entry
- move.l (a0),a6 ; get the pointer
- _HLock ; lock the DCE
-
- lea DiskDrvr,a0 ; point to the real stuff
- move.l a0,dCtlDriver(a6) ; install driver pointer
- move (a0)+,dCtlFlags(a6) ; driver flags -> DCE
- move.l (a0)+,dCtlDelay(a6) ; copy delay, emask
- move (a0)+,dCtlMenu(a6) ; and menu
- bset #dOpened,dCtlFlags+1(a6) ; mark the driver open
- bclr #dRamBased,dCtlFlags+1(a6) ; mark as ROM based (because DCE contains ptr)
-
- moveq.l #1,d0 ; assume we'll mount it
- btst.l #30,d5 ; bit 30 used as don't-mount flag
- beq.s @doopen ; not set, so mount as normal
- moveq.l #0,d0 ; bit set, so don't mount
- @doopen
- move.l d5,-(sp) ; Device Ident/SCSI ID
- move.l d0,-(sp) ; mountflag
- move.l a6,-(sp) ; DCE pointer
- jsr dropen ; return value in d0
- add.l #12,sp ; drop parameters
- tst.w d0
- beq.s InitExit ; branch if OK from open
- move.l #openErr,d0 ; failed...
- InitExit
- movem.l (sp)+,a2-a6/d2-d7
- rts
-
- ENDP
-
- ;*
- ;* 94.05.06
- ;* The asynchronous SCSI Manager calls this routine when a request completes.
- ;* It calls, in turn, a C completion routine that is responsible for continued requests
- ;* that may be needed to handle error retries. The C routine returns an OSErr or
- ;* the magic "1" value that indicates that another request is in-progress.
- ;* If a normal (non-magic) value is returned DRVRCOMPIO calls the normal Device
- ;* Manager ioDone procedure to complete driver processing for the original
- ;* Prime/Control/whatever request.
- ;*
- DRVRCOMPIO PROC EXPORT
- IMPORT completeIO, getDCE
- move.l 4(sp),-(sp) ; setup parameters
- jsr getDCE ; get the DCE from the parameter block
- move.l d0,a1 ; remember it for later
- move.l (sp)+,d1 ; remember parameter block
- move.l a1,-(sp) ; save dce
- move.l d1,-(sp) ; setup parameters again
- jsr completeIO ; execute the c completion routine
- add.l #4,sp ; clean up the stack
- move.l (sp)+,a1 ; and finally get the dce back (whew - that was too much work)
- cmp.w #1,d0 ; magic - we're not done yet?
- bne.b @done ; nope - call IODone
- move.l (sp)+,d1 ; remember return value
- add.l #4,sp ; clean up stack (Pascal style function)
- move.l d1,-(sp) ; restore return value
- rts ; rts back to SCSI Manager
- @done
- tst.w d0 ; set z bit for test <AG>
- beq.s @NoError ; ... don't update error field unless there is an error <AG>
- move.w d0,DskErr ; save last error for file system
- @NoError
- move.l (sp)+,d1 ; remember return value
- add.l #4,sp ; clean up stack (Pascal style function)
- move.l d1,-(sp) ; restore return value
- movem.l a2-a6/d2-d7,-(sp) ; save stuff around IO/Done
- move.l JIODone,a2 ; IODone...
- jsr (a2) ; jump to JIODone
- movem.l (sp)+,a2-a6/d2-d7 ; restore regs
- rts
- ENDP
- END
-